home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1998 March / Macworld (1998-03) (Disk 1).dmg / Shareware World / Info / For Developers / GhostScript 5.10 / MacGS-510 / files / gs_init.ps < prev    next >
Text File  |  1997-11-04  |  46KB  |  1,459 lines

  1. %    Copyright (C) 1989, 1996, 1997 Aladdin Enterprises.  All rights reserved.
  2. % This file is part of Aladdin Ghostscript.
  3. % Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
  4. % or distributor accepts any responsibility for the consequences of using it,
  5. % or for whether it serves any particular purpose or works at all, unless he
  6. % or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
  7. % License (the "License") for full details.
  8. % Every copy of Aladdin Ghostscript must include a copy of the License,
  9. % normally in a plain ASCII text file named PUBLIC.  The License grants you
  10. % the right to copy, modify and redistribute Aladdin Ghostscript, but only
  11. % under certain conditions described in the License.  Among other things, the
  12. % License requires that the copyright notice and this notice be preserved on
  13. % all copies.
  14.  
  15. % Initialization file for the interpreter.
  16. % When this is run, systemdict is still writable.
  17.  
  18. % Comment lines of the form
  19. %    %% Replace <n> <file(s)>
  20. % indicate places where the next <n> lines should be replaced by
  21. % the contents of <file(s)>, when creating a single merged init file.
  22.  
  23. % The interpreter can call out to PostScript code.  All procedures
  24. % called in this way, and no other procedures defined in these
  25. % initialization files, have names that begin with %, e.g.,
  26. % (%Type1BuildChar) cvn.
  27.  
  28. % Check the interpreter revision.  NOTE: the interpreter code requires
  29. % that the first non-comment token in this file be an integer.
  30. 510
  31. dup revision ne
  32.  { (gs: Interpreter revision \() print revision 10 string cvs print
  33.    (\) does not match gs_init.ps revision \() print 10 string cvs print
  34.    (\).\n) print flush null 1 .quit
  35.  }
  36. if pop
  37.  
  38. % Acquire userdict, and set its length if necessary.
  39. /userdict where
  40.  { pop userdict maxlength 0 eq }
  41.  { true }
  42. ifelse
  43.  {        % userdict wasn't already set up by iinit.c.
  44.    /userdict
  45.    currentdict dup 200 .setmaxlength        % userdict
  46.    systemdict begin def        % can't use 'put', userdict is local
  47.  }
  48.  { systemdict begin
  49.  }
  50. ifelse
  51.  
  52. % Define dummy local/global operators if needed.
  53. systemdict /.setglobal known
  54.  { true .setglobal
  55.  }
  56.  { /.setglobal { pop } bind def
  57.    /.currentglobal { false } bind def
  58.    /.gcheck { pop false } bind def
  59.  }
  60. ifelse
  61.  
  62. % Define .languagelevel if needed.
  63. systemdict /.languagelevel known not { /.languagelevel 1 def } if
  64.  
  65. % Optionally choose a default paper size other than U.S. letter.
  66. % (a4) /PAPERSIZE where { pop pop } { /PAPERSIZE exch def } ifelse
  67.  
  68. % Turn on array packing for the rest of initialization.
  69. true setpacking
  70.  
  71. % Define the old MS-DOS EOF character as a no-op.
  72. % This is a hack to get around the absurd habit of MS-DOS editors
  73. % of adding an EOF character at the end of the file.
  74. <1a> cvn { } def
  75.  
  76. % Acquire the debugging flags.
  77. currentdict /DEBUG known   /DEBUG exch def
  78.   /VMDEBUG
  79.     DEBUG {{print mark
  80.             systemdict /level2dict known
  81.          { .currentglobal dup false .setglobal vmstatus
  82.            true .setglobal vmstatus 3 -1 roll pop
  83.            6 -2 roll pop .setglobal
  84.          }
  85.          { vmstatus 3 -1 roll pop
  86.          }
  87.         ifelse usertime 16#fffff and counttomark
  88.           { ( ) print (           ) cvs print }
  89.         repeat pop
  90.         ( ) print systemdict length (    ) cvs print
  91.         ( ) print countdictstack (  ) cvs print
  92.         ( <) print count (  ) cvs print (>\n) print flush
  93.       }}
  94.       {{pop
  95.       }}
  96.      ifelse
  97.   def
  98.  
  99. currentdict /BATCH known   /BATCH exch def
  100. currentdict /DELAYBIND known   /DELAYBIND exch def
  101. currentdict /DISKFONTS known   /DISKFONTS exch def
  102. currentdict /ESTACKPRINT known   /ESTACKPRINT exch def
  103. currentdict /FAKEFONTS known   /FAKEFONTS exch def
  104. currentdict /FIXEDMEDIA known   /FIXEDMEDIA exch def
  105. currentdict /FIXEDRESOLUTION known   /FIXEDRESOLUTION exch def
  106. currentdict /LOCALFONTS known   /LOCALFONTS exch def
  107. currentdict /NOBIND known   /NOBIND exch def
  108. /.bind /bind load def
  109. NOBIND { /bind { } def } if
  110. currentdict /NOCACHE known   /NOCACHE exch def
  111. currentdict /NOCIE known   /NOCIE exch def
  112. currentdict /NODISPLAY known   not /DISPLAYING exch def
  113. currentdict /NOFONTMAP known   /NOFONTMAP exch def
  114. currentdict /NOFONTPATH known   /NOFONTPATH exch def
  115. currentdict /NOGC known   /NOGC exch def
  116. currentdict /NOPAUSE known   /NOPAUSE exch def
  117. currentdict /NOPLATFONTS known   /NOPLATFONTS exch def
  118. currentdict /NOPROMPT known   /NOPROMPT exch def
  119. % The default value of ORIENT1 is true, not false.
  120. currentdict /ORIENT1 known not { /ORIENT1 true def } if
  121. currentdict /OSTACKPRINT known   /OSTACKPRINT exch def
  122. currentdict /OUTPUTFILE known    % obsolete
  123.  { /OutputFile /OUTPUTFILE load def
  124.    currentdict /OUTPUTFILE .undef
  125.  } if
  126. currentdict /QUIET known   /QUIET exch def
  127. currentdict /SAFER known   /SAFER exch def
  128. currentdict /SHORTERRORS known   /SHORTERRORS exch def
  129. currentdict /WRITESYSTEMDICT known   /WRITESYSTEMDICT exch def
  130.  
  131. % Acquire environment variables.
  132. currentdict /DEVICE known not
  133.  { (GS_DEVICE) getenv { /DEVICE exch def } if } if
  134.  
  135. (START) VMDEBUG
  136.  
  137. % Open the standard files, so they will be open at the outermost save level.
  138. (%stdin) (r) file pop
  139. (%stdout) (w) file pop
  140. (%stderr) (w) file pop
  141.  
  142. % Define a procedure for skipping over an unneeded section of code.
  143. % This avoids allocating space for the skipped procedures.
  144. % We can't use readline, because that imposes a line length limit.
  145. /.skipeof    % <string> .skipeof -
  146.  { currentfile exch 1 exch .subfiledecode flushfile
  147.  } bind def
  148.  
  149. % If we're delaying binding, remember everything that needs to be bound later.
  150. DELAYBIND NOBIND not and
  151.  { .currentglobal false .setglobal
  152.    userdict /.delaybind 1500 array put
  153.    .setglobal
  154.    userdict /.delaycount 0 put
  155.     % When we've done the delayed bind, we want to stop saving.
  156.     % Detect this by the disappearance of .delaybind.
  157.    /bind
  158.     { userdict /.delaybind .knownget
  159.        { .delaycount 2 index put
  160.          userdict /.delaycount .delaycount 1 add put
  161.        }
  162.        { .bind
  163.        }
  164.       ifelse
  165.     } bind def
  166.  } if
  167.  
  168. % Define procedures to assist users who don't read the documentation.
  169. userdict begin
  170. /help
  171.  { (Enter PostScript commands.  '(filename) run' runs a file, 'quit' exits.\n)
  172.    print flush
  173.  } bind def
  174. /? /help load def
  175. end
  176.  
  177. % Define =string, which is used by some PostScript programs even though
  178. % it isn't documented anywhere.
  179. % Put it in userdict so that each context can have its own copy.
  180. userdict /=string 256 string put
  181.  
  182. % Print the greeting.
  183.  
  184. /printgreeting
  185.  { mark
  186.    product (Ghostscript) search
  187.     { pop pop pop
  188.       (This software comes with NO WARRANTY: see the file PUBLIC for details.\n)
  189.     }
  190.     { pop
  191.     }
  192.    ifelse
  193.    (\n) copyright
  194.    (\)\n) revisiondate 100 mod (-)
  195.    revisiondate 100 idiv 100 mod (-)
  196.    revisiondate 10000 idiv ( \()
  197.    revision 10 mod
  198.    revision 100 mod dup 0 ne { 10 idiv } { pop } ifelse (.)
  199.    revision 100 idiv ( )
  200.    product
  201.    counttomark
  202.     { (%stdout) (w) file exch false .writecvp
  203.     } repeat pop
  204.  } bind def
  205.  
  206. QUIET not { printgreeting flush } if
  207.  
  208. % Define a special version of def for making operator procedures.
  209. /odef        % <name> <proc> odef -
  210.  { 1 index exch .makeoperator def
  211.  } .bind def
  212.  
  213. %**************** BACKWARD COMPATIBILITY
  214. /getdeviceprops
  215.  { null .getdeviceparams
  216.  } bind odef
  217. /.putdeviceprops
  218.  { null true counttomark 1 add 3 roll .putdeviceparams
  219.    dup type /booleantype ne
  220.     { dup mark eq { /unknown /rangecheck } if
  221.       counttomark 4 add 1 roll cleartomark pop pop pop
  222.       /.putdeviceprops load exch signalerror
  223.     }
  224.    if
  225.  } bind odef
  226. /max { .max } bind def
  227. /min { .min } bind def
  228. /.currentfilladjust { .currentfilladjust2 pop } bind odef
  229. /.setfilladjust { dup .setfilladjust2 } bind odef
  230. /.writecvs { false .writecvp } bind odef
  231.  
  232. % Define predefined procedures substituting for operators,
  233. % in alphabetical order.
  234.  
  235. userdict /#copies 1 put
  236. % Adobe implementations don't accept /[ or /], so we don't either.
  237. ([) cvn
  238.     /mark load def
  239. (]) cvn
  240.     {counttomark array astore exch pop} odef
  241. /abs    {dup 0 lt {neg} if} odef
  242. % .beginpage is redefined if setpagedevice is present.
  243. /.beginpage { } odef
  244. /copypage
  245.     { 1 .endpage
  246.        { .currentnumcopies false .outputpage
  247.          (>>copypage, press <return> to continue<<\n) .confirm
  248.        }
  249.       if .beginpage
  250.     } odef
  251. /countexecstack { false .countexecstack } odef
  252. % .currentnumcopies is redefined in Level 2.
  253. /.currentnumcopies { #copies } odef
  254. /setcolorscreen where { pop        % not in all Level 1 configurations
  255.    /currentcolorscreen
  256.     { .currenthalftone
  257.        { { 60 exch 0 exch 3 copy 6 copy }    % halftone - not possible
  258.          { 3 copy 6 copy }            % screen
  259.          { }                % colorscreen
  260.        }
  261.       exch get exec
  262.     } odef
  263. } if
  264. /currentscreen
  265.     { .currenthalftone
  266.        { { 60 exch 0 exch }            % halftone - not possible
  267.          { }                % screen
  268.          { 12 3 roll 9 { pop } repeat }    % colorscreen
  269.        }
  270.       exch get exec
  271.     } odef
  272. /.echo /echo load def
  273. userdict /.echo.mode true put
  274. /echo    {dup /.echo.mode exch store .echo} odef
  275. /eexec
  276.     { 55665 //filterdict /eexecDecode get exec
  277.       cvx //systemdict begin exec
  278.         % Only pop systemdict if it is still the top element,
  279.         % because this is apparently what Adobe interpreters do.
  280.       currentdict //systemdict eq { end } if
  281.     } odef
  282. % .endpage is redefined if setpagedevice is present.
  283. /.endpage { 2 ne } odef
  284. % erasepage mustn't use gsave/grestore, because we call it before
  285. % the graphics state stack has been fully initialized.
  286. /erasepage
  287.     { /currentcolor where
  288.        { pop currentcolor currentcolorspace { setcolorspace setcolor } }
  289.        { /currentcmykcolor where
  290.           { pop currentcmykcolor { setcmykcolor } }
  291.           { currentrgbcolor { setrgbcolor } }
  292.          ifelse
  293.        }
  294.       ifelse 1 setgray .fillpage exec
  295.     } odef
  296. /execstack { false .execstack } odef
  297. /executive
  298.     { { prompt
  299.          { (%statementedit) (r) file } stopped
  300.          { pop pop $error /errorname get /undefinedfilename eq
  301.         { .clearerror exit } if        % EOF
  302.            handleerror null        % ioerror??
  303.          }
  304.         if
  305.         cvx { .runexec } execute
  306.       } loop
  307.     } odef
  308. /filter
  309.     { //filterdict 1 index .knownget
  310.        { exch pop exec }
  311.        { /filter load /undefined signalerror }
  312.       ifelse
  313.     } odef
  314. /handleerror
  315.     { //systemdict /errordict get /handleerror get exec } bind def
  316. /identmatrix [1.0 0.0 0.0 1.0 0.0 0.0] readonly def
  317. /identmatrix
  318.     { dup 0 //identmatrix putinterval } odef
  319. /languagelevel 1 def        % gs_lev2.ps may change this
  320. /makeimagedevice { false makewordimagedevice } odef
  321. /matrix    { 6 array identmatrix } odef
  322. /pathbbox
  323.     { false .pathbbox
  324.     } odef
  325. /prompt    { flush flushpage
  326.       (GS) print
  327.       count 0 ne { (<) print count =only } if
  328.       (>) print flush
  329.     } bind def
  330. /pstack    { 0 1 count 3 sub { index == } for } bind def
  331. /putdeviceprops
  332.     { .putdeviceprops { erasepage } if } odef
  333. /quit    { /quit load 0 .quit } odef
  334. /run    { dup type /filetype ne { (r) file } if
  335.         % We must close the file when execution terminates,
  336.         % regardless of the state of the stack,
  337.         % and then propagate an error, if any.
  338.       cvx .runexec
  339.     } odef
  340. % Execute a file.
  341. % Level 2 uses 2 .stop to clear the e-stack for a successful startjob:
  342. % we detect that here, since we need to handle this even if we start out
  343. % without job control in effect.
  344. %
  345. % What we push on the e-stack is the following to be executed in this order:
  346. %    <lit-file|fileproc> .runexec1 <lit-file|fileproc> .runexec2
  347. /.runexec1 {        % <file|fileproc> .runexec1 -
  348.   dup type /filetype ne { cvx exec } if
  349.   cvx null 2 .stopped
  350.     % If we got back here from a startjob, just keep going.
  351.     % startjob replaces the null on the o-stack with a procedure
  352.     % to be executed when we get back here.
  353.   dup null ne { exec true } { pop false } ifelse
  354. } bind def
  355. /.runexec2 {        % <continue> <file|fileproc> .runexec2 -
  356.   exch {
  357.     .runexec
  358.   } {
  359.     dup type /filetype ne { cvx exec } if
  360.     closefile
  361.   } ifelse
  362. } bind def
  363. /.runexec {        % <file|fileproc> .runexec -
  364.   cvlit /.runexec1 cvx 1 index /.runexec2 cvx 4 .execn
  365. } bind def
  366. % The following is only for compatibility with Adobe interpreters.
  367. /setdash {
  368.     1 index length 11 gt { /setdash load /limitcheck signalerror } if
  369.     //setdash
  370. } odef
  371. /setdevice
  372.     { .setdevice { erasepage } if } odef
  373. /setlinecap {
  374.     dup 2 gt { /setlinecap load /rangecheck signalerror } if
  375.     .setlinecap
  376. } odef
  377. /setlinejoin {
  378.     dup 2 gt { /setlinejoin load /rangecheck signalerror } if
  379.     .setlinejoin
  380. } odef
  381. /showpage
  382.     { 0 .endpage .doneshowpage
  383.        { .currentnumcopies true .outputpage
  384.          (>>showpage, press <return> to continue<<\n) .confirm
  385.          erasepage
  386.        }
  387.       if initgraphics .beginpage
  388.     } odef
  389. % Code output by Adobe Illustrator relies on the fact that
  390. % `stack' is a procedure, not an operator!!!
  391. /stack    { 0 1 count 3 sub { index = } for } bind def
  392. /start    { BATCH { null 0 .quit } { executive } ifelse } def
  393. % Internal uses of stopped that aren't going to do a stop if an error occurs
  394. % should use .internalstopped to avoid setting newerror et al.
  395. /.internalstopped { null 1 .stopped null ne } bind def
  396. /store    {    % Don't alter operands before completing.
  397.       1 index where { 2 index 2 index put pop pop } { def } ifelse
  398.     } odef
  399. % When running in Level 1 mode, this interpreter is supposed to be
  400. % compatible with PostScript "version" 54.0 (I think).
  401. /version (54.0) def
  402.  
  403. % internaldict is defined in systemdict, but is allocated in local VM.
  404. systemdict /internaldict .knownget not { 0 } if type /operatortype ne
  405.  { .currentglobal false .setglobal
  406.    //systemdict /internaldict known not { /internaldict 5 dict def } if
  407.    /internaldict
  408.     [ /dup load 1183615869 /eq load
  409.        [ /pop load internaldict ] cvx
  410.        [ /internaldict /cvx load /invalidaccess /signalerror cvx ] cvx
  411.       /ifelse load
  412.     ] cvx bind odef
  413.    .setglobal
  414.  } if
  415.  
  416. % Define some additional built-in procedures (beyond the ones defined by
  417. % the PostScript Language Reference Manual).
  418. % Warning: these are not guaranteed to stay the same from one release
  419. % to the next!
  420. /concatstrings
  421.     { exch dup length 2 index length add string    % str2 str1 new
  422.       dup dup 4 2 roll copy        % str2 new new new1
  423.       length 4 -1 roll putinterval
  424.     } bind def
  425. /copyarray
  426.     { dup length array copy } bind def
  427. % Copy a dictionary per the Level 2 spec even in Level 1.
  428. /.copydict        % <fromdict> <todict> .copydict <todict>
  429.     { dup 3 -1 roll { put dup } forall pop } bind def
  430. /copystring
  431.     { dup length string copy } bind def
  432. /finddevice
  433.     { //systemdict /devicedict get exch get
  434.       dup 1 get null eq
  435.        {        % This is the first request for this type of device.
  436.             % Create a default instance now.
  437.             % Stack: [proto null]
  438.          .currentglobal true .setglobal exch
  439.          dup dup 0 get copydevice 1 exch put
  440.          exch .setglobal
  441.        }
  442.       if 1 get
  443.     } bind def
  444. /.growdictlength    % get size for growing a dictionary
  445.     { length 3 mul 2 idiv 1 add
  446.     } bind def
  447. /.growdict        % grow a dictionary
  448.     { dup .growdictlength .setmaxlength
  449.     } bind def
  450. /.growput        % put, grow the dictionary if needed
  451.     { 2 index length 3 index maxlength eq
  452.        { 3 copy pop known not { 2 index .growdict } if
  453.        } if
  454.       put
  455.     } bind def
  456. /.packtomark
  457.     { counttomark packedarray exch pop } bind def
  458. /ppstack
  459.     { 0 1 count 3 sub { index === } for } bind def
  460. /runlibfile
  461.     {        % We don't want to bind 'run' into this procedure,
  462.             % since run may get redefined.
  463.       findlibfile
  464.        { exch pop //systemdict /run get exec }
  465.        { /undefinedfilename signalerror }
  466.       ifelse
  467.     } bind def
  468. /selectdevice
  469.     { finddevice setdevice .setdefaultscreen } bind def
  470. /signalerror        % <object> <errorname> signalerror -
  471.     { //systemdict /errordict get exch get exec } bind def
  472.  
  473. % Define the =[only] procedures.  Also define =print,
  474. % which is used by some PostScript programs even though
  475. % it isn't documented anywhere.
  476. /write=only {
  477.     .writecvs
  478. } bind def
  479. /write= {
  480.     1 index exch write=only (\n) writestring
  481. } bind def
  482. /=only    { (%stdout) (w) file exch write=only } bind def
  483. /=    { =only (\n) print } bind def
  484. /=print    /=only load def
  485. % Temporarily define == as = for the sake of runlibfile0.
  486. /== /= load def
  487.  
  488. % Define procedures for getting and setting the current device resolution.
  489.  
  490. /gsgetdeviceprop    % <device> <propname> gsgetdeviceprop <value>
  491.  { 2 copy mark exch null .dicttomark .getdeviceparams
  492.    dup mark eq        % if true, not found
  493.     { pop dup /undefined signalerror }
  494.     { 5 1 roll pop pop pop pop }
  495.    ifelse
  496.  } bind def
  497. /gscurrentresolution    % - gscurrentresolution <[xres yres]>
  498.  { currentdevice /HWResolution gsgetdeviceprop
  499.  } bind def
  500. /gssetresolution    % <[xres yres]> gssetresolution -
  501.  { 2 array astore mark exch /HWResolution exch
  502.    currentdevice copydevice putdeviceprops setdevice
  503.  } bind def
  504.  
  505. % Define auxiliary procedures needed for the above.
  506. /shellarguments        % -> shell_arguments true (or) false
  507.     { /ARGUMENTS where
  508.        { /ARGUMENTS get dup type /arraytype eq
  509.           { aload pop /ARGUMENTS null store true }
  510.           { pop false }
  511.          ifelse }
  512.        { false } ifelse
  513.     } bind def
  514. /.confirm
  515.     { DISPLAYING NOPAUSE not and
  516.        {    % Print a message (unless NOPROMPT is true)
  517.         % and wait for the user to type something.
  518.         % If the user just types a newline, flush it.
  519.          NOPROMPT { pop } { print flush } ifelse
  520.          .echo.mode false echo
  521.          (%stdin) (r) file dup read
  522.           { dup (\n) 0 get eq { pop pop } { unread } ifelse }
  523.           { pop }
  524.          ifelse echo
  525.        }
  526.        { pop
  527.        }
  528.       ifelse
  529.     } bind def
  530.  
  531. % Define the procedure used by .runfile, .runstdin and .runstring
  532. % for executing user input.
  533. % This is called with a procedure or executable file on the operand stack.
  534. /.execute {        % <obj> .execute <stopped>
  535.   stopped $error /newerror get and
  536.    { handleerror flush true } { false } ifelse
  537. } bind def
  538. /execute {        % <obj> execute -
  539.   .execute pop
  540. } odef
  541. % Define an execute analogue of runlibfile0.
  542. /execute0 {        % <obj> execute0 -
  543.   .execute { /execute0 cvx 1 .quit } if
  544. } bind def
  545. % Define the procedure that the C code uses for running files
  546. % named on the command line.
  547. /.runfile {
  548.   { runlibfile } execute
  549. } def
  550. % Define the procedure that the C code uses for running piped input.
  551. % We don't use the obvious { (%stdin) run }, because we want the file to be
  552. % reopened if a startjob does a restore.
  553. /.runstdin {
  554.   { { (%stdin) (r) file cvx } .runexec } execute0
  555. } bind def
  556. % Define the procedure that the C code uses for running commands
  557. % given on the command line with -c.  We turn the string into a file so that
  558. % .runexec can do the right thing with a startjob.
  559. /.runstring {
  560.   .currentglobal exch true .setglobal
  561.   0 () .subfiledecode
  562.   exch .setglobal cvx { .runexec } execute
  563. } bind def
  564. % Define the procedure that the C code uses to set up for executing
  565. % a string that may be received in pieces.
  566. /.runstringbegin {
  567.   .currentglobal true .setglobal
  568.   { .needinput } bind 0 () .subfiledecode
  569.   exch .setglobal cvx .runexec
  570. } bind def
  571.  
  572. % Define a special version of runlibfile that aborts on errors.
  573. /runlibfile0
  574.     { cvlit dup /.currentfilename exch def
  575.        { findlibfile not { stop } if }
  576.       stopped
  577.        { (Can't find \(or open\) initialization file ) print
  578.          .currentfilename == flush /runlibfile0 cvx 1 .quit
  579.        } if
  580.       exch pop cvx stopped
  581.        { (While reading ) print .currentfilename print (:\n) print flush
  582.          handleerror /runlibfile0 1 .quit
  583.        } if
  584.     } bind def
  585. % Temporarily substitute it for the real runlibfile.
  586. /.runlibfile /runlibfile load def
  587. /runlibfile /runlibfile0 load def
  588.  
  589. % Create the error handling machinery.
  590. % Define the standard error handlers.
  591. % The interpreter has created the ErrorNames array.
  592. /.unstoppederrorhandler    % <command> <errorname> .unstoppederrorhandler -
  593.  {    % This is the handler that gets used for recursive errors,
  594.     % or errors outside the scope of a 'stopped'.
  595.    2 copy SHORTERRORS
  596.     { (%%[ Error: ) print =only flush
  597.       (; OffendingCommand: ) print =only ( ]%%\n) print
  598.     }
  599.     { (Unrecoverable error: ) print =only flush
  600.       ( in ) print = flush
  601.       count 2 gt
  602.        { (Operand stack:\n  ) print
  603.      2 1 count 3 sub { (  ) print index =only flush } for
  604.      (\n) print flush
  605.        } if
  606.     }
  607.    ifelse
  608.    -1 0 1 //ErrorNames length 1 sub
  609.     { dup //ErrorNames exch get 3 index eq
  610.        { not exch pop exit } { pop } ifelse
  611.     }
  612.    for exch pop .quit
  613.  } bind def
  614. /.errorhandler        % <command> <errorname> .errorhandler -
  615.   {        % Detect an internal 'stopped'.
  616.     1 .instopped { null eq { pop pop stop } if } if
  617.     $error /.inerror get 1 .instopped { pop } { pop true } ifelse
  618.      { .unstoppederrorhandler
  619.      } if    % detect error recursion
  620.     $error /globalmode .currentglobal false .setglobal put
  621.     $error /.inerror true put
  622.     $error /newerror true put
  623.     $error exch /errorname exch put
  624.     $error exch /command exch put
  625.     $error /recordstacks get $error /errorname get /VMerror ne and
  626.      {        % Attempt to store the stack contents atomically.
  627.        count array astore dup $error /ostack 4 -1 roll
  628.        countexecstack array execstack $error /estack 3 -1 roll
  629.        countdictstack array dictstack $error /dstack 3 -1 roll
  630.        put put put aload pop
  631.      }
  632.      { $error /dstack .undef
  633.        $error /estack .undef
  634.        $error /ostack .undef
  635.      }
  636.     ifelse
  637.     $error /position currentfile status
  638.      { currentfile { fileposition } .internalstopped { pop null } if
  639.      }
  640.      {        % If this was a scanner error, the file is no longer current,
  641.         % but the command holds the file, which may still be open.
  642.        $error /command get dup type /filetype eq
  643.         { { fileposition } .internalstopped { pop null } if }
  644.         { pop null }
  645.        ifelse
  646.      }
  647.     ifelse put
  648.         % During initialization, we don't reset the allocation
  649.         % mode on errors.
  650.     $error /globalmode get $error /.nosetlocal get and .setglobal
  651.     $error /.inerror false put
  652.     stop
  653.   } bind def
  654. % Define the standard handleerror.  We break out the printing procedure
  655. % (.printerror) so that it can be extended for binary output
  656. % if the Level 2 facilities are present.
  657.   /.printerror
  658.    { $error begin
  659.        /command load errorname SHORTERRORS
  660.     { (%%[ Error: ) print =only flush
  661.       (; OffendingCommand: ) print =only
  662.       currentdict /errorinfo .knownget
  663.        { (;\nErrorInfo:) print
  664.          dup type /arraytype eq
  665.           { { ( ) print =only } forall }
  666.           { ( ) print =only }
  667.          ifelse
  668.        } if
  669.           ( ]%%\n) print flush
  670.     }
  671.     { (Error: ) print ==only flush
  672.       ( in ) print ==only flush
  673.       currentdict /errorinfo .knownget
  674.        { (\nAdditional information: ) print ==only flush
  675.        } if
  676.       .printerror_long
  677.     }
  678.        ifelse
  679.        .clearerror
  680.      end
  681.      flush
  682.     } bind def     
  683.   /.printerror_long            % long error printout,
  684.                     % $error is on the dict stack
  685.    {    % Push the (anonymous) stack printing procedure.
  686.     %  <heading> <==flag> <override-name> <stackname> proc
  687.        {
  688.      currentdict exch .knownget    % stackname defined in $error?
  689.      {
  690.        4 1 roll            % stack: <stack> <head> <==flag> <over>
  691.        errordict exch .knownget    % overridename defined?
  692.        { 
  693.          exch pop exch pop exec    % call override with <stack>
  694.        }
  695.        { 
  696.          exch print exch        % print heading. stack <==flag> <stack>
  697.          1 index not { (\n) print } if
  698.          { 1 index { (\n    ) } { (   ) } ifelse print
  699.            dup type /dicttype eq
  700.            {
  701.          (--dict:) print
  702.          dup rcheck
  703.           { dup length =only (/) print maxlength =only }
  704.           { pop }
  705.          ifelse
  706.          (--) print
  707.            }
  708.            {
  709.          dup type /stringtype eq 2 index or
  710.          { ===only } { =only } ifelse
  711.            } ifelse
  712.          } forall
  713.          pop
  714.        }
  715.        ifelse            % overridden
  716.      }
  717.      { pop pop pop
  718.      }
  719.      ifelse                % stack known
  720.        }
  721.  
  722.        (\nOperand stack:) OSTACKPRINT /.printostack /ostack 4 index exec
  723.        (\nExecution stack:) ESTACKPRINT /.printestack /estack 4 index exec
  724.        (\nBacktrace:) true /.printbacktrace /backtrace 4 index exec
  725.        (\nDictionary stack:) false /.printdstack /dstack 4 index exec
  726.        (\n) print
  727.        pop    % printing procedure
  728.  
  729.        errorname /VMerror eq
  730.     { (VM status:) print mark vmstatus
  731.       counttomark { ( ) print counttomark -1 roll dup =only } repeat
  732.       cleartomark (\n) print
  733.     } if
  734.  
  735.        .languagelevel 2 ge
  736.     { (Current allocation mode is ) print
  737.       globalmode { (global\n) } { (local\n) } ifelse print
  738.     } if
  739.  
  740.        .oserrno dup 0 ne
  741.     { (Last OS error: ) print
  742.       errorname /VMerror ne
  743.        { dup .oserrorstring { = pop } { = } ifelse }
  744.        { = }
  745.       ifelse
  746.     }
  747.     { pop
  748.     }
  749.        ifelse
  750.  
  751.        position null ne
  752.     { (Current file position is ) print position = }
  753.        if
  754.  
  755.    } bind def
  756. % Define a procedure for clearing the error indication.
  757. /.clearerror
  758.  { $error /newerror false put
  759.    $error /errorname null put
  760.    $error /errorinfo .undef
  761.    0 .setoserrno
  762.  } bind def
  763.  
  764. % Define $error.  This must be in local VM.
  765. .currentglobal false .setglobal
  766. /$error 40 dict def        % newerror, errorname, command, errorinfo,
  767.                 % ostack, estack, dstack, recordstacks,
  768.                 % binary, globalmode,
  769.                 % .inerror, .nosetlocal, position,
  770.         % plus extra space for badly designed error handers.
  771. $error begin
  772.   /newerror false def
  773.   /recordstacks true def
  774.   /binary false def
  775.   /globalmode .currentglobal def
  776.   /.inerror false def
  777.   /.nosetlocal true def
  778.   /position null def
  779. end
  780. % Define errordict similarly.  It has one entry per error name,
  781. %   plus handleerror.
  782. /errordict ErrorNames length 1 add dict def
  783. .setglobal        % contents of errordict are global
  784. errordict begin
  785.   ErrorNames
  786.    { mark 1 index systemdict /.errorhandler get /exec load .packtomark cvx def
  787.    } forall
  788. % The handlers for interrupt and timeout are special; there is no
  789. % 'current object', so they push their own name.
  790.    { /interrupt /timeout }
  791.    { mark 1 index dup systemdict /.errorhandler get /exec load .packtomark cvx def
  792.    } forall
  793. /handleerror
  794.  { //systemdict /.printerror get exec
  795.  } bind def
  796. end
  797.  
  798. % Define the [write]==[only] procedures.
  799. /.dict 26 dict dup
  800. begin def
  801.   /.cvp {1 index exch .writecvs} bind def
  802.   /.nop {exch pop .p} bind def
  803.   /.p {1 index exch writestring} bind def
  804.   /.p1 {2 index exch writestring} bind def
  805.   /.p2 {3 index exch writestring} bind def
  806.   /.print
  807.     { dup type .dict exch .knownget
  808.        { dup type /stringtype eq { .nop } { exec } ifelse }
  809.        { (-) .p1 type .cvp (-) .p }
  810.       ifelse
  811.     } bind def
  812.   /.pstring
  813.     {  { dup dup 32 lt exch 127 ge or
  814.           { (\\) .p1 2 copy -6 bitshift 48 add write
  815.         2 copy -3 bitshift 7 and 48 add write
  816.         7 and 48 add
  817.           }
  818.           { dup dup -2 and 40 eq exch 92 eq or {(\\) .p1} if
  819.           }
  820.          ifelse 1 index exch write
  821.        }
  822.       forall
  823.     } bind def  
  824.   /booleantype /.cvp load def
  825.   /conditiontype (-condition-) def
  826.   /devicetype (-device-) def
  827.   /dicttype (-dict-) def
  828.   /filetype (-file-) def
  829.   /fonttype (-fontID-) def
  830.   /gstatetype (-gstate-) def
  831.   /integertype /.cvp load def
  832.   /locktype (-lock-) def
  833.   /marktype (-mark-) def
  834.   /nulltype (null) def
  835.   /realtype {1 index exch true .writecvp} bind def
  836.   /savetype (-save-) def
  837.   /nametype
  838.     {dup xcheck not {(/) .p1} if
  839.      1 index exch .writecvs} bind def
  840.   /arraytype
  841.     {dup rcheck
  842.       {() exch dup xcheck
  843.         {({) .p2
  844.          {exch .p1
  845.           1 index exch .print pop ( )} forall
  846.          (})}
  847.         {([) .p2
  848.          {exch .p1
  849.           1 index exch .print pop ( )} forall
  850.          (])}
  851.        ifelse exch pop .p}
  852.       {(-array-) .nop}
  853.      ifelse} bind def
  854.   /operatortype
  855.       {(--) .p1 .cvp (--) .p} bind def
  856.   /packedarraytype
  857.     { dup rcheck
  858.        { arraytype }
  859.        { (-packedarray-) .nop }
  860.       ifelse
  861.     } bind def
  862.   /stringtype
  863.     { dup rcheck
  864.        { (\() .p1 dup length 200 le
  865.           { .pstring }
  866.           { 0 200 getinterval .pstring (...) .p }
  867.          ifelse (\)) .p
  868.        }
  869.        { (-string-) .nop
  870.        }
  871.       ifelse
  872.     } bind def
  873. {//.dict begin .print pop end}
  874.   bind
  875. end
  876.  
  877. /write==only exch def
  878. /write== {1 index exch write==only (\n) writestring} bind def
  879. /==only { (%stdout) (w) file exch write==only } bind def
  880. /== {==only (\n) print} bind def
  881.  
  882. % Define [write]===[only], an extension that prints dictionaries
  883. % in readable form and doesn't truncate strings.
  884. /.dict /write==only load 0 get dup length dict .copydict dup
  885. begin def
  886.   /dicttype
  887.     { dup rcheck
  888.        { (<< ) .p1
  889.           { 2 index 3 -1 roll .print pop ( ) .p1
  890.         1 index exch .print pop ( ) .p
  891.           }
  892.          forall (>>) .p
  893.        }
  894.        { (-dict-) .nop
  895.        }
  896.       ifelse
  897.     } bind def
  898.   /stringtype
  899.     { dup rcheck
  900.        { (\() .p1 .pstring (\)) .p }
  901.        { (-string-) .nop }
  902.       ifelse
  903.     } bind def
  904.  
  905. {//.dict begin .print pop end}
  906.   bind
  907. end
  908.  
  909. /write===only exch def
  910. /write=== {1 index exch write===only (\n) writestring} bind def
  911. /===only { (%stdout) (w) file exch write===only } bind def
  912. /=== { ===only (\n) print } bind def
  913.  
  914. (END PROCS) VMDEBUG
  915.  
  916. % Define the font directory.
  917. /FontDirectory false .setglobal 100 dict true .setglobal def
  918.  
  919. % Define the encoding dictionary.
  920. /EncodingDirectory 10 dict def    % enough for Level 2 + PDF standard encodings
  921.  
  922. % Define .findencoding.  (This is redefined in Level 2.)
  923. /.findencoding
  924.  { //EncodingDirectory exch get exec
  925.  } bind def
  926. /.defineencoding
  927.  { //EncodingDirectory 3 1 roll put
  928.  } bind def
  929. % If we've got the composite font extensions, define findencoding.
  930. /rootfont where { pop /findencoding { .findencoding } odef } if
  931.  
  932. % Load StandardEncoding.
  933. %% Replace 1 (gs_std_e.ps)
  934. (gs_std_e.ps) dup runlibfile VMDEBUG
  935.  
  936. % Load ISOLatin1Encoding.
  937. %% Replace 1 (gs_iso_e.ps)
  938. (gs_iso_e.ps) dup runlibfile VMDEBUG
  939.  
  940. % Define stubs for the Symbol and Dingbats encodings.
  941. % Note that the first element of the procedure must be the file name,
  942. % since gs_lev2.ps extracts it to set up the Encoding resource category.
  943.  
  944.   /SymbolEncoding { /SymbolEncoding .findencoding } bind def
  945. %% Replace 3 (gs_sym_e.ps)
  946.   EncodingDirectory /SymbolEncoding
  947.    { (gs_sym_e.ps) //systemdict begin runlibfile SymbolEncoding end }
  948.   bind put
  949.  
  950.   /DingbatsEncoding { /DingbatsEncoding .findencoding } bind def
  951. %% Replace 3 (gs_dbt_e.ps)
  952.   EncodingDirectory /DingbatsEncoding
  953.    { (gs_dbt_e.ps) //systemdict begin runlibfile DingbatsEncoding end }
  954.   bind put
  955.  
  956. (END FONTDIR/ENCS) VMDEBUG
  957.  
  958. % Construct a dictionary of all available devices.
  959. % These are (read-only) device prototypes that can't be
  960. % installed or have their parameters changed.  For this reason,
  961. % the value in the dictionary is actually a 2-element writable array,
  962. % to allow us to create a default instance of the prototype on demand.
  963.  
  964.     % Loop until the .getdevice gets a rangecheck.
  965. errordict /rangecheck 2 copy get
  966. errordict /rangecheck { pop stop } put    % pop the command
  967.   0 { {dup .getdevice exch 1 add} loop} .internalstopped pop
  968.   1 add dict  /devicedict 1 index def
  969.   begin            % 2nd copy of count is on stack
  970.    { dup .devicename exch
  971.      dup wcheck { dup } { null } ifelse 2 array astore def
  972.    } repeat
  973.   end
  974. put        % errordict /rangecheck
  975. .clearerror
  976. /devicenames devicedict { pop } forall devicedict length packedarray def
  977.  
  978. % Determine the default device.
  979. /defaultdevice DISPLAYING
  980.  { systemdict /DEVICE .knownget
  981.     { devicedict 1 index known not
  982.        { (Unknown device: ) print =
  983.      flush /defaultdevice cvx 1 .quit
  984.        }
  985.       if
  986.     }
  987.     { 0 .getdevice .devicename
  988.     }
  989.    ifelse
  990.  }
  991.  { /nullpage
  992.  }
  993. ifelse
  994. /.defaultdevicename 1 index def
  995. finddevice    % make a copy
  996. def
  997. devicedict /Default devicedict .defaultdevicename get put
  998.  
  999. (END DEVS) VMDEBUG
  1000.  
  1001. % Define statusdict, for the benefit of programs
  1002. % that think they are running on a LaserWriter or similar printer.
  1003. %% Replace 1 (gs_statd.ps)
  1004. (gs_statd.ps) runlibfile
  1005.  
  1006. (END STATD) VMDEBUG
  1007.  
  1008. % Load the standard font environment.
  1009. %% Replace 1 (gs_fonts.ps)
  1010. (gs_fonts.ps) runlibfile
  1011.  
  1012. (END GS_FONTS) VMDEBUG
  1013.  
  1014. % Load the initialization files for optional features.
  1015. %% Replace 4 INITFILES
  1016. systemdict /INITFILES known
  1017.  { INITFILES { dup runlibfile VMDEBUG } forall
  1018.  }
  1019. if
  1020.  
  1021. % If Level 2 functionality is implemented, enable it now.
  1022. /.setlanguagelevel where
  1023.  { pop 2 .setlanguagelevel
  1024.     % If the resource machinery is loaded, fix up some things now.
  1025.    /.fixresources where { pop .fixresources } if
  1026.  } if
  1027.  
  1028. (END INITFILES) VMDEBUG
  1029.  
  1030. % Create a null font.  This is the initial font.
  1031. 8 dict dup begin
  1032.   /FontMatrix [ 1 0 0 1 0 0 ] readonly def
  1033.   /FontType 3 def
  1034.   /FontName () def
  1035.   /Encoding StandardEncoding def
  1036.   /FontBBox { 0 0 0 0 } readonly def % executable is bogus, but customary ...
  1037.   /BuildChar { pop pop 0 0 setcharwidth } bind def
  1038.   /PaintType 0 def        % shouldn't be needed!
  1039. end
  1040. /NullFont exch definefont setfont
  1041.  
  1042. % Define NullFont as the font.
  1043. /NullFont currentfont def
  1044.  
  1045. % Load initial fonts from FONTPATH directories, Fontmap file,
  1046. % and/or .getccfont as appropriate.
  1047. .loadinitialfonts
  1048.  
  1049. % Remove NullFont from FontDirectory, so it can't be accessed by mistake.
  1050. FontDirectory /NullFont .undef
  1051.  
  1052. (END FONTS) VMDEBUG
  1053.  
  1054. % Restore the real definition of runlibfile.
  1055. /runlibfile /.runlibfile load def
  1056. currentdict /.runlibfile .undef
  1057.  
  1058. % Bind all the operators defined as procedures.
  1059. /.bindoperators        % binds operators in currentdict
  1060.  { % Temporarily disable the typecheck error.
  1061.    errordict /typecheck 2 copy get
  1062.    errordict /typecheck { pop } put    % pop the command
  1063.    currentdict
  1064.     { dup type /operatortype eq
  1065.        { % This might be a real operator, so bind might cause a typecheck,
  1066.      % but we've made the error a no-op temporarily.
  1067.      .bind        % do a real bind even if NOBIND is set
  1068.        }
  1069.       if pop pop
  1070.     } forall
  1071.    put
  1072.  } def
  1073. NOBIND DELAYBIND or not { .bindoperators } if
  1074.  
  1075. % Establish a default environment.
  1076.  
  1077. defaultdevice
  1078. DISPLAYING not { setdevice (%END DISPLAYING) .skipeof } if
  1079. systemdict /DEVICEWIDTH known
  1080. systemdict /DEVICEHEIGHT known or
  1081. systemdict /DEVICEWIDTHPOINTS known or
  1082. systemdict /DEVICEHEIGHTPOINTS known or
  1083. systemdict /DEVICEXRESOLUTION known or
  1084. systemdict /DEVICEYRESOLUTION known or
  1085. systemdict /PAPERSIZE known or
  1086. not { (%END DEVICE) .skipeof } if
  1087. % Let DEVICE{WIDTH,HEIGHT}[POINTS] override PAPERSIZE.
  1088. systemdict /PAPERSIZE known
  1089. systemdict /DEVICEWIDTH known not and
  1090. systemdict /DEVICEHEIGHT known not and
  1091. systemdict /DEVICEWIDTHPOINTS known not and
  1092. systemdict /DEVICEHEIGHTPOINTS known not and
  1093.  {    % Convert the paper size to device dimensions.
  1094.    true statusdict /.pagetypenames get
  1095.     { PAPERSIZE eq
  1096.        { PAPERSIZE load
  1097.          dup 0 get /DEVICEWIDTHPOINTS exch def
  1098.          1 get /DEVICEHEIGHTPOINTS exch def
  1099.          pop false exit
  1100.        }
  1101.       if
  1102.     }
  1103.    forall
  1104.     { (Unknown paper size: ) print PAPERSIZE ==only (.\n) print
  1105.     }
  1106.    if
  1107.  }
  1108. if
  1109. % Adjust the device parameters per the command line.
  1110. % It is possible to specify resolution, pixel size, and page size;
  1111. % since any two of these determine the third, conflicts are possible.
  1112. % We simply pass them to .setdeviceparams and let it sort things out.
  1113.    mark /HWResolution null /HWSize null /PageSize null .dicttomark
  1114.    .getdeviceparams .dicttomark begin
  1115.    mark
  1116.     % Check for resolution.
  1117.    /DEVICEXRESOLUTION where dup
  1118.     { exch pop HWResolution 0 DEVICEXRESOLUTION put }
  1119.    if
  1120.    /DEVICEYRESOLUTION where dup
  1121.     { exch pop HWResolution 1 DEVICEYRESOLUTION put }
  1122.    if
  1123.    or { /HWResolution HWResolution } if
  1124.     % Check for device sizes specified in pixels.
  1125.    /DEVICEWIDTH where dup
  1126.     { exch pop HWSize 0 DEVICEWIDTH put }
  1127.    if
  1128.    /DEVICEHEIGHT where dup
  1129.     { exch pop HWSize 1 DEVICEHEIGHT put }
  1130.    if
  1131.    or { /HWSize HWSize } if
  1132.     % Check for device sizes specified in points.
  1133.    /DEVICEWIDTHPOINTS where dup
  1134.     { exch pop PageSize 0 DEVICEWIDTHPOINTS put }
  1135.    if
  1136.    /DEVICEHEIGHTPOINTS where dup
  1137.     { exch pop PageSize 1 DEVICEHEIGHTPOINTS put }
  1138.    if
  1139.    or { /PageSize PageSize } if
  1140.     % Check whether any parameters were set.
  1141.    dup mark eq { pop } { defaultdevice putdeviceprops } ifelse
  1142.    end
  1143. %END DEVICE
  1144. % Set any device properties defined on the command line.
  1145. % If BufferSpace is defined but not MaxBitmap, set MaxBitmap to BufferSpace.
  1146. systemdict /BufferSpace known
  1147. systemdict /MaxBitmap known not and
  1148.  { systemdict /MaxBitmap BufferSpace put
  1149.  } if
  1150. dup getdeviceprops
  1151. counttomark 2 idiv
  1152.  { systemdict 2 index known
  1153.     { pop dup load counttomark 2 roll }
  1154.     { pop pop }
  1155.    ifelse
  1156.  } repeat
  1157. counttomark dup 0 ne
  1158.  { 2 add -1 roll putdeviceprops }
  1159.  { pop pop }
  1160. ifelse
  1161. setdevice        % does an erasepage
  1162. % If the media size is fixed, update the current page device dictionary.
  1163. FIXEDMEDIA
  1164. dup { pop systemdict /.currentpagedevice known } if
  1165. dup { pop .currentpagedevice exch pop } if
  1166. not { (%END MEDIA) .skipeof } if
  1167. currentpagedevice dup length dict .copydict
  1168. dup /Policies
  1169.     % Stack: <pagedevice> <pagedevice> /Policies
  1170. 1 index /InputAttributes
  1171. 2 copy get dup length dict .copydict
  1172.     % Stack: <pagedevice> <pagedevice> /Policies <pagedevice>
  1173.     %   /InputAttributes <inputattrs'>
  1174. dup 0 2 copy get dup length dict .copydict
  1175.     % Stack: <pagedevice> <pagedevice> /Policies <pagedevice>
  1176.     %   /InputAttributes <inputattrs'> <inputattrs'> 0 <attrs0'>
  1177. dup /PageSize 7 index /PageSize get
  1178. put                % PageSize in 0
  1179. put                % 0 in InputAttributes
  1180. put                % InputAttributes in pagedevice
  1181. % Also change the page size policy so we don't get an error.
  1182.     % Stack: <pagedevice> <pagedevice> /Policies
  1183. 2 copy get dup length dict .copydict
  1184.     % Stack: <pagedevice> <pagedevice> /Policies <policies'>
  1185. dup /PageSize 7 put        % PageSize in Policies
  1186. put                % Policies in pagedevice
  1187. .setpagedevice
  1188. %END MEDIA
  1189. %END DISPLAYING
  1190.  
  1191. (END DEVICE) VMDEBUG
  1192.  
  1193. % Establish a default upper limit in the character cache,
  1194. % namely, enough room for a 18-point character at the resolution
  1195. % of the default device, or for a character consuming 1% of the
  1196. % maximum cache size, whichever is larger.
  1197. mark
  1198.     % Compute limit based on character size.
  1199.   18 dup dtransform
  1200.   exch abs cvi 31 add 32 idiv 4 mul    % X raster
  1201.   exch abs cvi mul        % Y
  1202.     % Compute limit based on allocated space.
  1203.   cachestatus pop pop pop pop pop exch pop 0.01 mul cvi
  1204.   .max dup 10 idiv exch
  1205. setcacheparams
  1206. % Conditionally disable the character cache.
  1207. NOCACHE { 0 setcachelimit } if
  1208.  
  1209. (END CONFIG) VMDEBUG
  1210.  
  1211. % Establish an appropriate halftone screen and BG/UCR functions.
  1212. % We make this a procedure so we can call it again when switching devices.
  1213.  
  1214. % Use an ordered dither for low-resolution devices.
  1215. /.setloresscreen    % <dpi> .setloresscreen -
  1216.  {    % The following 'ordered dither' spot function was contributed by
  1217.     % Gregg Townsend.  Thanks, Gregg!
  1218.    16.001 div 0            % not 16: avoids rounding problems
  1219.     { 1 add 7.9999 mul cvi exch 1 add 7.9999 mul cvi 16 mul add <
  1220.     0E 8E 2E AE 06 86 26 A6 0C 8C 2C AC 04 84 24 A4
  1221.     CE 4E EE 6E C6 46 E6 66 CC 4C EC 6C C4 44 E4 64
  1222.     3E BE 1E 9E 36 B6 16 96 3C BC 1C 9C 34 B4 14 94
  1223.     FE 7E DE 5E F6 76 D6 56 FC 7C DC 5C F4 74 D4 54
  1224.     01 81 21 A1 09 89 29 A9 03 83 23 A3 0B 8B 2B AB
  1225.     C1 41 E1 61 C9 49 E9 69 C3 43 E3 63 CB 4B EB 6B
  1226.     31 B1 11 91 39 B9 19 99 33 B3 13 93 3B BB 1B 9B
  1227.     F1 71 D1 51 F9 79 D9 59 F3 73 D3 53 FB 7B DB 5B
  1228.     0D 8D 2D AD 05 85 25 A5 0F 8F 2F AF 07 87 27 A7
  1229.     CD 4D ED 6D C5 45 E5 65 CF 4F EF 6F C7 47 E7 67
  1230.     3D BD 1D 9D 35 B5 15 95 3F BF 1F 9F 37 B7 17 97
  1231.     FD 7D DD 5D F5 75 D5 55 FF 7F DF 5F F7 77 D7 57
  1232.     02 82 22 A2 0A 8A 2A AA 00 80 20 A0 08 88 28 A8
  1233.     C2 42 E2 62 CA 4A EA 6A C0 40 E0 60 C8 48 E8 68
  1234.     32 B2 12 92 3A BA 1A 9A 30 B0 10 90 38 B8 18 98
  1235.     F2 72 D2 52 FA 7A DA 5A F0 70 D0 50 F8 78 D8 58
  1236.      > exch get 256 div
  1237.     }
  1238.    bind
  1239.         % Use correct, per-plane screens for CMYK devices only.
  1240.    //systemdict /setcolorscreen known processcolors 4 eq and
  1241.     { 3 copy 6 copy setcolorscreen }
  1242.     { setscreen }
  1243.    ifelse
  1244.    0 array cvx settransfer    % Genoa CET won't accept a packed array!
  1245.    /setstrokeadjust where { pop true setstrokeadjust } if
  1246.  } bind def
  1247. % Use a 45-degree spot screen for high-resolution devices.
  1248. /.sethiresscreen    % <dpi> .sethiresscreen -
  1249.  {    % According to information published by Hewlett-Packard,
  1250.     % they use a 60 line screen on 300 DPI printers and
  1251.     % an 85 line screen on 600 DPI printers.
  1252.     % However, we use a 106 line screen, which produces smoother-
  1253.     % looking shades but fewer of them (32 vs. 50).
  1254.     % 46 was suggested as a good frequency value for printers
  1255.     % between 200 and 400 DPI, so we use it for lower resolutions.
  1256.     % Imagesetters need even higher frequency screens.
  1257.    //systemdict /DITHERPPI known
  1258.     { DITHERPPI
  1259.     }
  1260.     { dup cvi 100 idiv 15 .min
  1261.        {null 46 46 60 60 60 106 106 106 106 133 133 133 133 133 150}
  1262.       exch get
  1263.      }
  1264.    ifelse
  1265.    1 index 4.01 div .min    % at least a 4x4 cell
  1266.    45
  1267.     % The following screen algorithm is used by permission of the author.
  1268.     { 1 add 180 mul cos 1 0.08 add mul exch 2 add 180 mul cos 
  1269.       1 0.08 sub mul add 2 div % (C) 1989 Berthold K.P. Horn
  1270.     }
  1271.    bind
  1272.     % Determine whether we have lots of process colors.
  1273.     % If so, don't bother with color screening or gamma correction.
  1274.     % Also don't do gamma correction on very high-resolution devices.
  1275.     % (This should depend on dot gain, not resolution, but we don't
  1276.     % currently have a way to determine this.)
  1277.    currentdevice mark
  1278.      /RedValues 0 /GreenValues 0 /BlueValues 0 /GrayValues 0
  1279.    .dicttomark .getdeviceparams
  1280.    counttomark 2 idiv 1 sub { exch pop min } repeat
  1281.    exch pop exch pop 32 lt 4 index 800 lt and 5 1 roll
  1282.     % Stack: doscreen dpi freq angle proc
  1283.     % Ghostscript currently doesn't use correct, per-plane halftones
  1284.     % unless setcolorscreen has been executed.  Since these are
  1285.     % computationally much more expensive than binary halftones,
  1286.     % we check to make sure they are really warranted, i.e., we have
  1287.     % a high-resolution CMYK device (i.e., not a display) with
  1288.     % fewer than 5 bits per plane (i.e., not a true-color device).
  1289.    4 -1 roll 150 ge
  1290.     { /setcolorscreen where
  1291.        { pop //systemdict /COLORSCREEN known
  1292.       { COLORSCREEN }
  1293.       { 3 index }
  1294.      ifelse
  1295.      dup false ne
  1296.       { 4 1 roll 3 copy 6 copy 13 -1 roll
  1297.     % For really high-quality screening on printers, we need to
  1298.     % give each plane its own screen angle.  Unfortunately,
  1299.     % this currently has very large space and time costs.
  1300.         true eq        % true => different angles,
  1301.                 % 0 => same angles
  1302.          { { 45 90 15 75 } { 3 1 roll exch pop 12 3 roll } forall
  1303.          }
  1304.         if setcolorscreen
  1305.       }
  1306.       { pop setscreen    % false => single binary screen
  1307.       }
  1308.      ifelse
  1309.        }
  1310.        { setscreen        % setcolorscreen not known
  1311.        }
  1312.       ifelse
  1313.     }
  1314.     { setscreen            % not high resolution
  1315.     }
  1316.    ifelse
  1317.             % Stack: doscreen
  1318.     {    % Set the transfer function to lighten up the grays.
  1319.     % We correct at the high end so that very light grays
  1320.     % don't disappear completely if they darken <1 screen pixel.
  1321.     % Parameter values closer to 1 are better for devices with
  1322.     % less dot spreading; lower values are better with more spreading.
  1323.     % The value 0.8 is a compromise that will probably please no one!
  1324.     %
  1325.     % Because of a bug in FrameMaker, we have to accept operands
  1326.     % outside the valid range of [0..1].
  1327.       { dup dup 0.0 gt exch 1.0 lt and
  1328.      { 0.8 exp dup dup 0.9375 gt exch 0.999 lt and    % > 15/16
  1329.         { .currentscreenlevels 1 sub    % tweak to avoid boundary
  1330.           1 exch div 1 exch sub .min
  1331.         }
  1332.        if
  1333.      }
  1334.     if
  1335.       }
  1336.     }
  1337.     {    % Set the transfer function to the identity.
  1338.       0 array cvx        % Genoa CET won't accept a packed array!
  1339.     }
  1340.    ifelse settransfer
  1341.    /setstrokeadjust where { pop false setstrokeadjust } if
  1342.     % Increase fill adjustment so that we effectively use Adobe's
  1343.     % any-part-of-pixel rule.
  1344.    0.5 .setfilladjust
  1345.  } bind def
  1346. % Set the default screen and BG/UCR based on the device resolution and
  1347. % process color capability.
  1348. /.setdefaultbgucr systemdict /setblackgeneration known { {
  1349.   processcolors 1 eq { { } } { { pop 0.0 } } ifelse
  1350.   dup setblackgeneration setundercolorremoval
  1351. } } { {
  1352. } } ifelse bind def
  1353. /.setdefaultscreen
  1354.  {    % Compute min(|dpi x|,|dpi y|) as the definition of the resolution.
  1355.    72 72 matrix defaultmatrix dtransform abs exch abs .min
  1356.    dup 150 lt //systemdict /DITHERPPI known not and
  1357.     { .setloresscreen } { .sethiresscreen }
  1358.    ifelse .setdefaultbgucr
  1359.  } bind def
  1360. .setdefaultscreen
  1361. initgraphics
  1362.  
  1363. % The interpreter relies on there being at least 2 entries
  1364. % on the graphics stack.  Establish the second one now.
  1365. gsave
  1366.  
  1367. % Define some control sequences as no-ops.
  1368. % This is a hack to get around problems
  1369. % in some common PostScript-generating applications.
  1370. <04> cvn { } def        % Apple job separator
  1371. <0404> cvn { } def        % two of the same
  1372. <1b> cvn { } def        % MS Windows LaserJet 4 prologue
  1373.                 % (UEL = ESC %-12345X)
  1374. <1b45> cvn { } def        % PJL reset prologue (ESC E)
  1375. <1b451b> cvn { } def        % PJL reset epilogue (ESC E + UEL)
  1376. <041b> cvn { } def        % MS Windows LaserJet 4 epilogue (^D + UEL)
  1377. (\001M) cvn            % TBCP initiator
  1378.  { currentfile /TBCPDecode filter cvx exec
  1379.  } bind def
  1380. /@PJL                % H-P job control
  1381.  { currentfile //=string readline { pop } if
  1382.  } bind def
  1383.  
  1384. % If we want a "safer" system, disable some obvious ways to cause havoc.
  1385. SAFER not { (%END SAFER) .skipeof } if
  1386. /file
  1387.  { dup (r) eq 2 index (%pipe*) .stringmatch not and
  1388.    2 index (%std*) .stringmatch or
  1389.     { file }
  1390.     { /invalidfileaccess signalerror }
  1391.    ifelse
  1392.  } .bind odef
  1393. /renamefile { /invalidfileaccess signalerror } odef
  1394. /deletefile { /invalidfileaccess signalerror } odef
  1395. /putdeviceprops
  1396.  { counttomark
  1397.    dup 2 mod 0 eq { pop /rangecheck signalerror } if
  1398.    3 2 3 2 roll
  1399.     { dup index /OutputFile eq  
  1400.        { -2 roll 
  1401.          dup () ne { /putdeviceprops load /invalidfileaccess signalerror } if
  1402.          3 -1 roll
  1403.        }
  1404.        { pop
  1405.        }
  1406.       ifelse
  1407.     } for
  1408.    putdeviceprops
  1409.  } .bind odef
  1410.  
  1411. %END SAFER
  1412.  
  1413. % If we delayed binding, make it possible to do it later.
  1414. /.bindnow
  1415.  { //systemdict begin .bindoperators end
  1416.    % Temporarily disable the typecheck error.
  1417.    errordict /typecheck 2 copy get
  1418.    errordict /typecheck { pop } put    % pop the command
  1419.    0 1 .delaycount 1 sub { .delaybind exch get .bind pop } for
  1420.    userdict /.delaybind .undef        % reclaim the space
  1421.    userdict /.delaycount .undef
  1422.    put
  1423.  } .bind def
  1424.  
  1425. % Turn off array packing, since some PostScript code assumes that
  1426. % procedures are writable.
  1427. false setpacking
  1428.  
  1429. % Close up systemdict.
  1430. currentdict /.forceput .undef        % remove temptation
  1431. currentdict /filterdict .undef        % bound in where needed
  1432. end
  1433. WRITESYSTEMDICT not { systemdict readonly pop } if
  1434.  
  1435. (END INIT) VMDEBUG
  1436.  
  1437. % Since some badly-behaved files include extremely long procedures,
  1438. % or construct huge arrays on the operand stack, increase the operand
  1439. % stack size here.
  1440. /setuserparams where
  1441.  { pop mark /MaxOpStack 20000 .dicttomark setuserparams
  1442.  } if
  1443.  
  1444. % Establish local VM as the default.
  1445. false /setglobal where { pop setglobal } { .setglobal } ifelse
  1446. $error /.nosetlocal false put
  1447.  
  1448. % Clean up VM, and enable GC.
  1449. /vmreclaim where
  1450.  { pop NOGC not { 2 vmreclaim 0 vmreclaim } if
  1451.  } if
  1452.  
  1453. (END GC) VMDEBUG
  1454.  
  1455. % The interpreter will run the initial procedure (start).
  1456.